/*   Copyright (C) 2008  Jeroen v. Schagen & Youri Lima
 *
 *   This program is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Collections;

using Engine;
using Engine.Connection;
using Engine.Connection.Server;

namespace GameServer
{
    public partial class GameServerForm : Form
    {
        private TCPServer server;
        private int count;

        public GameServerForm()
        {
            InitializeComponent();
            count = 0;

            // Initiate server
            server = new TCPServer("Game");

            // Attach events
            server.ClientConnect += new ClientEventHandler(server_ClientConnect);
            server.ClientDisconnect += new ClientEventHandler(server_ClientDisconnect);
            server.DataRecieved += new PackageEventHandler(server_DataRecieved);
            server.StatusChanged += new StatusEventHandler(server_StatusChanged);

            // Disable cross thread exceptions
            Control.CheckForIllegalCrossThreadCalls = false;
        }

        public static void Main()
        {
            // Configure logger
            Engine.Logger.Configure("data/config/log4net.cfg.xml");

            // Run application
            Application.Run(new GameServerForm());
        }

        // Append message
        public void AppendMessage(string message)
        {
            String timestamp = "[" + DateTime.Now.Hour + ":" + DateTime.Now.Minute + ":" + DateTime.Now.Second + "] ";
            txfConsole.AppendText(timestamp + message + "\r\n");
        }

        // Server callbacks
        private void server_StatusChanged(object sender)
        {
            txfStatus.Text = server.Connected ? "Online" : "Offline";
        }

        private void server_ClientConnect(object sender, User client)
        {
            txfClients.Text = server.Clients.Count + "";
        }

        private void server_ClientDisconnect(object sender, User client)
        {
            txfClients.Text = server.Clients.Count + "";
        }

        private void server_DataRecieved(object sender, Packet package)
        {
            // Decode package
            byte[] buffer = package.DataBuffer;
            char[] chars = new char[buffer.Length];

            Decoder d = Encoding.ASCII.GetDecoder();
            d.GetChars(buffer, 0, buffer.Length, chars, 0);

            String data = new String(chars);
            AppendMessage(data);

            try
            {
                // Update request
                if (data.StartsWith("/update"))
                {
                    char[] array = data.ToCharArray();

                    // Create message
                    String message = data;

                    // Send data
                    server.Send(Encoding.ASCII.GetBytes(message));
                }

                // Name request
                else if (data.StartsWith("/name"))
                {
                    String message = "/name flip" + count;
                    count++;

                    // Send data
                    server.Send(Encoding.ASCII.GetBytes(message));
                }

                // Invalid command
                else
                {
                    // Create message
                    String message = String.Format("'{0}' is not a valid command.", data);

                    // Send data
                    server.Send(Encoding.ASCII.GetBytes(message), package.User);
                }
            }

            // Process exception
            catch (Exception e)
            {
                // Display script
                Console.WriteLine("Exception occured while proccesing script '" + data + "'.");

                // Display exception
                Console.WriteLine(e);
            }
        }

        // Form callbacks
        private void startToolStripMenuItem_Click(object sender, EventArgs e)
        {
            server.Listen(Int32.Parse(txfPort.Text));
        }

        private void rebootToolStripMenuItem_Click(object sender, EventArgs e)
        {
            server.Close();
            server.Listen(Int32.Parse(txfPort.Text));
        }

        private void disconnectToolStripMenuItem_Click(object sender, EventArgs e)
        {
            server.Close();
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void btnBroadcast_Click(object sender, EventArgs e)
        {
            if (txfMessage.Text != "")
            {
                server.Send(Encoding.ASCII.GetBytes(txfMessage.Text));

                txfMessage.Text = "";
                txfMessage.Focus();
            }
        }

        private void GameServerForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            disconnectToolStripMenuItem_Click(sender, e);
        }
    }
}